/**
 * Copyright (c) 2018, wuxie All rights reserved.
 * qq:16349023,mail:16349023@qq.com
 * 未经许可禁止任何人通过任何渠道使用、修改源代码.
 * 项目名称 : wxcloud
 *
 * @version V1.0
 */
package cn.xo68.boot.auth.server.web.token;

import cn.xo68.boot.auth.core.domain.Oauth2Principal;
import cn.xo68.boot.auth.core.exception.OperateException;
import cn.xo68.boot.auth.server.domain.OauthResource;
import cn.xo68.boot.auth.server.domain.OauthToken;
import cn.xo68.boot.auth.server.service.OauthRefreshTokenService;
import cn.xo68.boot.auth.server.service.OauthResourceService;
import cn.xo68.boot.auth.server.service.OauthRoleResourceService;
import cn.xo68.boot.auth.server.service.OauthTokenService;
import cn.xo68.core.util.StringTools;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 *  用户信息
 * @author wuxie
 * @date 2018/8/4 18:43
 *
 */
@RestController
public class UserInfoController {

    private static final Logger logger= LoggerFactory.getLogger(UserInfoController.class);

    @Autowired
    private OauthResourceService oauthResourceService;

    @Autowired
    private OauthRoleResourceService oauthRoleResourceService;
    @Autowired
    private OauthTokenService oauthTokenService;
    @Autowired
    private OauthRefreshTokenService oauthRefreshTokenService;

    @Autowired
    private SimpleCookie accessTokenCookie;

    @GetMapping({"/client/userinfo"})
    public Oauth2Principal info(Subject subject,Oauth2Principal oauth2Principal,
                       @RequestParam(name = "client_id",required = false, defaultValue = "authServer") String clientId,
                       HttpServletRequest request, HttpServletResponse response) throws OperateException {

        logger.debug("client_id: {}", clientId);
        if(subject!=null && subject.isAuthenticated()){
            return oauth2Principal;
        }else {
            throw new OperateException("鉴权失败");
        }
    }

    /**
     * 登录用户 指定应用的资源
     * @param subject
     * @param oauth2Principal
     * @param clientId
     * @param request
     * @param response
     * @return
     * @throws OperateException
     */
    @GetMapping({"/client/resource"})
    public List<OauthResource> resource(Subject subject, Oauth2Principal oauth2Principal,
                                @RequestParam(name = "client_id",required = false, defaultValue = "authServer") String clientId,
                                HttpServletRequest request, HttpServletResponse response) throws OperateException {

         //oauth2Principal.getUserId();
        List<OauthResource> appResources = oauthResourceService.list(clientId);

        final Set<String> userResourceIds=new HashSet<>();

        List<String> roles= oauth2Principal.getRoles();
        roles.forEach(roleId -> {
            userResourceIds.addAll(oauthRoleResourceService.listRoleResourcs(roleId, clientId));
        });
        List<OauthResource> userResources=appResources.stream().filter(oauthResource -> {
            return userResourceIds.contains(oauthResource.getResourceId());
        }).collect(Collectors.toList());

        //logger.info("userResourceIds: {}", userResourceIds);

        return userResources;
    }

    @GetMapping({"/client/logout"})
    public String logout(Subject subject, Oauth2Principal oauth2Principal,HttpServletRequest request, HttpServletResponse response) throws OperateException {
        if(subject!=null && subject.isAuthenticated()){
            //return oauth2Principal;
            OauthToken oauthToken = oauthTokenService.get(oauth2Principal.getAccessToken());
            if(oauthToken!=null){
                if(StringTools.isNotEmpty(oauthToken.getRefreshToken())){
                    oauthRefreshTokenService.delete(oauthToken.getRefreshToken());
                }
                oauthTokenService.delete(oauthToken.getToken());

                accessTokenCookie.setValue("");
                accessTokenCookie.saveTo(request,response);

            }
        }else {
            return "退出失败，认证信息不存在";
        }
        return "退出登录成功";
    }
}
